package com.kantboot.auth.filter;


import com.alibaba.fastjson2.JSON;
import com.kantboot.auth.exception.AuthException;
import com.kantboot.functional.common.service.ICommonKantbootRsaService;
import com.kantboot.system.user.service.ISysPermissionService;
import com.kantboot.util.common.exception.BaseException;
import com.kantboot.util.common.http.HttpRequestHeaderUtil;
import jakarta.annotation.Resource;
import jakarta.servlet.*;
import jakarta.servlet.annotation.WebFilter;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

@Slf4j
@Component
@Order(1)
@WebFilter(filterName = "authFilter", urlPatterns = {"/**"})
public class AuthFilter implements Filter {

    @Resource
    private HttpRequestHeaderUtil httpRequestHeaderUtil;

    @Resource
    private ICommonKantbootRsaService kantbootRsaService;

    @Resource
    private ISysPermissionService permissionService;

    /**
     * 用户是否可通行
     */
    private boolean isUserCanPass(ServletRequest servletRequest, ServletResponse servletResponse){
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        String requestURI = request.getRequestURI();

        String kantbootMemory = httpRequestHeaderUtil.getKantbootMemory();
        // 如果kantbootMemory不为空，说明是安全的登录，需要解密token
        if (kantbootMemory != null) {
            try{
                String token = kantbootRsaService.decryptAndDelete(kantbootMemory);
                // 将通过kantbootMemory解密出来的token放入request中
                request.setAttribute(HttpRequestHeaderUtil.FIELD_TOKEN, token);
            }catch (BaseException e){
                throw AuthException.KANTBOOT_MEMORY_ERROR;
            }
        }


        // 删除requestURI中?后面的内容
        if (requestURI.contains("?")) {
            requestURI = requestURI.substring(0, requestURI.indexOf("?"));
        }

        List<String> selfUriList =  permissionService.getSelfUriList();

        // 获取所有有星号的uri
        List<String> hasStarUriList = new ArrayList<>();
        for (String uri : selfUriList) {
            if (uri.contains("*")) {
                hasStarUriList.add(uri.replaceAll("/\\*\\*", ""));
            }
        }


        if (selfUriList.stream().anyMatch(requestURI::equals)) {
            return true;
        }

        return hasStarUriList.stream().anyMatch(requestURI::startsWith);
    }

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        log.info("过滤器初始化了");
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        // 开始时间
        long startTime = System.currentTimeMillis();

        servletResponse.setContentType("application/json;charset=utf-8");
        servletResponse.setCharacterEncoding("UTF-8");

        try{
            if(isUserCanPass(servletRequest,servletResponse)){
                // 结束时间
                long endTime = System.currentTimeMillis();
                log.info("过滤时间：{}ms",endTime-startTime);
                filterChain.doFilter(servletRequest, servletResponse);
                return;
            }
        }catch (BaseException e){
            servletResponse.getWriter().write(JSON.toJSONString(e.exceptionHandler(e)));
            // 结束时间
            long endTime = System.currentTimeMillis();
            log.info("过滤时间：{}ms",endTime-startTime);
            return;
        }


        // 告之前端没有权限
        servletResponse.getWriter().write(JSON.toJSONString(new BaseException().exceptionHandler(BaseException.of("noPermission", "无权限访问"))));
        // 结束时间
        long endTime = System.currentTimeMillis();
        log.info("过滤时间：{}ms",endTime-startTime);

    }

    @Override
    public void destroy() {
    }
}